import javassist.*;

import java.util.*;

public class ExtractSuperclass {
    public ExtractSuperclass(String dir) {
        this.dir = dir;
        init();
    }

    public Map<String, String> getResult() {
        return result;
    }

    public StringBuilder getArrangeResult() {
        StringBuilder sb = new StringBuilder();

        Iterator it = result.entrySet().iterator();
        while(it.hasNext()) {
            sb.append("\n");
          
            Map.Entry e = (Map.Entry)it.next();
            String c = (String)e.getKey();
            String v = (String)e.getValue();

            sb.append(c);

            String vs[] = v.split(":");

            for(int i=0; i<vs.length; i++) {
                for(int j=0; j<i; j++) {
                    sb.append("   ");
                }
                sb.append(vs[i] + "\n");
            }
        }

        return sb;
    }

    private void doIt() {
        JavassistAdapter ja = new JavassistAdapter(dir);
        List<String> classes = ja.getResult();

        Iterator<String> iter = classes.iterator();
        while( iter.hasNext() ) {
            String path = iter.next();

            CtClass cc = null;
            try {
                cc = pool.get(path);
            } catch(NotFoundException nfe) {
                nfe.printStackTrace();
                continue;
            } catch(Exception e) {
                e.printStackTrace();
                return;
            }

            extracSuperClassInfo(cc);
            extracSuperInterfaceInfo(cc);
        }    
    }

    private void extracSuperClassInfo(CtClass cc) {
        if(cc.isInterface()) {
            return;
        }

        CtClass cct;
        String name = cc.getName();
        String sname = "";
        String last = ""; //i need it, so i can judget if it is root class which cc extend

        try {
            while((cct=cc.getSuperclass()) != null) {
                String cctN = cct.getName();

                if(cctN==null || cctN.equals(last))
                    break;

                sname += (":" + cctN);

                last = cctN;
            }
        } catch(Exception e) {
            e.printStackTrace();
            sname += "";
        }

        if(!sname.equals(""))
            result.put(name, sname);
        else
            System.out.println(name + "'s super class is Object");

    }

    private void extracSuperInterfaceInfo(CtClass cc) {
        if(!cc.isInterface()) return;
    }

    private void init() {
        try {
            pool.appendPathList(this.dir);
        } catch(Exception e) {
            e.printStackTrace();
        } 

        doIt();
    }

    public static final void main(String []args) {
        StringBuilder sb = (new ExtractSuperclass(args[0])).getArrangeResult();

        System.out.println(sb.toString());
    }

    private String dir;
    private Map<String, String> result = new HashMap<String, String>();

    private ClassPool pool = ClassPool.getDefault();
}
